import React, { useEffect, useMemo, type RefObject } from "react";
import { Layout } from "antd";
import { useDebounceFn } from "ahooks";
import { useGlobalStore } from "@/store/global";
import { useShallow } from "zustand/react/shallow";
import { useMenuStore } from "@/store/menus";
import { KeepAlive, useKeepAliveRef, type KeepAliveRef } from "keepalive-for-react";
import { useKeepAliveInsRef } from "@/hooks/modules/useKeepAliveInsRef";
import { useLocation, useOutlet } from "react-router";
import Maximize from "./components/Maximize";
import LayoutTabs from "@/layouts/components/Tabs";
import LayoutFooter from "@/layouts/components/Footer";
import "./index.scss";

const { Content } = Layout;

const LayoutMain: React.FC = () => {
  const outlet = useOutlet();
  const keepAliveInsRef = useKeepAliveRef();

  const { pathname, search } = useLocation();
  const { setKeepAliveInsRef } = useKeepAliveInsRef();

  const { maximize } = useGlobalStore(useShallow((state) => ({ maximize: state.maximize })));
  const { isCollapse, flatMenuList, setCollapsed } = useMenuStore(useShallow((state) => ({ isCollapse: state.isCollapse, flatMenuList: state.flatMenuList, setCollapsed: state.setCollapsed })));

  // 监听窗口更改，折叠菜单
  const { run } = useDebounceFn(
    () => {
      const screenWidth = document.body.clientWidth;
      const shouldCollapse = screenWidth < 1200;
      if (isCollapse !== shouldCollapse) setCollapsed(shouldCollapse);
    },
    { wait: 100 }
  );

  useEffect(() => {
    window.addEventListener("resize", run, false);
    return () => {
      window.removeEventListener("resize", run);
    };
  }, []);

  // 监听路由缓存实例变化，全局缓存实例
  useEffect(() => {
    setKeepAliveInsRef(keepAliveInsRef?.current as KeepAliveRef);
  }, [keepAliveInsRef.current]);

  // 监听当前页面是否最大化，动态添加类
  useEffect(() => {
    const root = document.getElementById("root") as HTMLElement;
    root.classList.toggle("main-maximize", maximize);
  }, [maximize]);

  // 确定哪个路由组件处于活动状态
  const currentCacheKey = useMemo(() => pathname + search, [pathname, search]);

  // 缓存的路由 path
  const includeKeepAlivePaths = useMemo(() => flatMenuList.flatMap((item) => (item.meta?.isKeepAlive ? [item.path] : [])), [flatMenuList]);

  return (
    <React.Fragment>
      <Maximize />
      <LayoutTabs />
      <Content>
        <KeepAlive transition aliveRef={keepAliveInsRef as RefObject<KeepAliveRef>} activeCacheKey={currentCacheKey} include={includeKeepAlivePaths}>
          {outlet}
        </KeepAlive>
      </Content>
      <LayoutFooter />
    </React.Fragment>
  );
};

export default LayoutMain;
